/**
 * lab化合物反应的任务
*/
import { State } from "framework/FSM/AState";
import { LabTaskHelper } from "utils/task/LabTaskHelper";
import { LabUtils } from "./LabUtils";
import { ActionArgHelper } from "GameLoop/Execution/ControlManager/Control/ActionManager/ActionArgHelper";
import { generateUniqueId } from "utils/utils";
import { CoreEntity, LabEntity } from "GameLoop/WorldState/EntityManager/Entitys";
import { BoostState } from "GameLoop/WorldState/EntityManager/Entitys/room/lab/types";
 
export class Boost_State<T extends IStateArg<Room >> extends State<T>
{

    public getActions(arg:T):Action[]
    {
        
        const tasks = arg.entity.getTaskByType("boost"); // 所有boost任务
        if(!tasks || tasks.length==0)
        {
            return []
        }
        const labentity = arg.entity.getEntity("LabEntity");
        const memory = labentity.getNodeMemory();
        const validTasks =  memory.boostTasks.filter(e=> arg.entity.findTaskById(e,"boost")) 
        if(validTasks.length ==0)
        {
            // 已经强化完了
            labentity.resetLabState();
            return []
        }
        const boosttasks = memory.boostTasks.map(e=> arg.entity.findTaskById(e,"boost")) as ITask<ILabTaskData<"boost">>[];
        if(boosttasks.length ==0)
        {
            labentity.endBoost();
            return []
        }
        
        const coreEntity = arg.entity.getEntity("CoreEntity");
        
        if(labentity.isLabsShouldClear())
        {
            if(!memory.transportId || !arg.entity.findTaskById(memory.transportId,"creep") )
            {
                const transportargs=this.getTransportOut(memory,coreEntity,labentity);
                if(transportargs.length>0)
                {
                    memory.transportId  = generateUniqueId();
                    return [ActionArgHelper.actionClearLabs(arg.entity,
                        transportargs ,memory.transportId)]
                }
            }
            else
            {
                // 正在运输中
            }
        }
      
        if(!memory.transportId || !arg.entity.findTaskById(memory.transportId,"creep"))
        {
            const code = labentity.isLabResourceReady();
            if(code === OK)
            {
                
                // 可以准备反应。标记所有任务为已经就绪
                boosttasks.forEach(e=>
                    {
                        e.data.arg.State = BoostState.ready;
                        e.data.arg.res.forEach(r=>r.lab = labentity.inquireMinerialLab(r.resource));
                    })
            }
            else if(code == -1)
            {
                
                // 填充资源
                if(!memory.transportId || !arg.entity.findTaskById(memory.transportId,"creep") )
                {
                    const transportargs=this.getTransportIn(memory,coreEntity);
                  
                    if(transportargs.length>0)
                    {
                        memory.transportId  = generateUniqueId();
                        return [ActionArgHelper.actionFillLab(arg.entity,
                            transportargs,memory.transportId)]
                    }
                }
                else
                {
                    // 正在运输中
                }
            }
            else  if(code == -2)
            {
                labentity.reallocLab();
            }
        }
        // 房间爬虫绑定
        // 返回的Action为一组可以立即执行的Action命令参数
        return [];
    }

    // 填充boost材料
    private getTransportIn(memory:ILabMemory,coreEntity:CoreEntity )
    {
        const minerials = memory.minerialRecord;

        const transportparam:LabTranportItemArg[]=[];
        for(const minerial in minerials)
        {
            const type = minerial as MineralBoostConstant;
            const  lab = Game.getObjectById(minerials[type].lab) as StructureLab;
            if(!lab)
            {
                continue;
            }
            let  transfer_amount =minerials[type].amount;

            if(lab.mineralType)
            {
                if(transfer_amount<=lab.store.getUsedCapacity(lab.mineralType))
                {
                    continue;
                }
                transfer_amount = transfer_amount- lab.store.getUsedCapacity(lab.mineralType);
            }
            if(transfer_amount>3000)
            {
                global.Log.Error(`计算错误 lab化合物资源不能超过 3000 [${JSON.stringify(minerials)}]`);
            }
            const storeobj = coreEntity.getTakeStores({resourceType:type,amount:transfer_amount});
            if(transfer_amount>0&& storeobj.length>0)
            {
                const item :LabTranportItemArg={store:storeobj[0],lab: lab,amount:transfer_amount,resourceType:type};
                transportparam.push(item);
            }
        }
        return transportparam
    }
    // 不要的boost材料运输出去
    public getTransportOut(memory:ILabMemory,coreEntity:CoreEntity,labentity:LabEntity)
    {
        const minerials =  memory.minerialRecord;
 
        const transportparam:LabTranportItemArg[]=[];
        const boostlabs = labentity.BoostLabs();
        const minerial_count:Record<string,number>={};
        for(const lab of boostlabs)
        {
            if(lab && lab.mineralType  )
            {
                if(!minerials[lab.mineralType as MineralBoostConstant] || minerial_count[lab.mineralType ])
                {
                    let transfer_amount = lab.store.getUsedCapacity(lab.mineralType);
                    const storeobj = coreEntity.getStores({resourceType:lab.mineralType,amount:transfer_amount});
                    const item :LabTranportItemArg={lab:lab,store: storeobj[0],amount:transfer_amount,resourceType:lab.mineralType};
                    transportparam.push(item);
                }
                minerial_count[lab.mineralType ]=1;
            }
        }
        // global.Log.Info(`Boost Clear->Run ${JSON.stringify(transportparam)}  `);
        return transportparam;
    }
}
